feat(brand): draw the small-size optical cut at chrome sizes - #2473
Conversation
The follow-up recorded in PR #2462 and deliberately left undone there, now that the artwork decision has been made: the app rendered the mark's *display* geometry at every size, including the 28-32px chrome where the brand's own construction calls for a different cut. **Why this is the real fix.** The mark is a construction, not a bitmap, so it does not simply get smaller. Two pieces of its negative space close up first — the 4.2-unit cut between the strokes and the 7.26-unit crescent around the point — and when the crescent closes, the dot fuses into the S. That fuses the top of the mark into one solid blob above a lower stroke that is already the thinner read, which is exactly the top-heavy look this branch previously compensated for with the deeper `--brand-mark-emphasis` ink. The ink stays; the cause is now addressed rather than offset. `docs/brand/psychsift-logo.md` §"Small sizes" already specifies the remedy and `brand-mark.ts` already ships it: `BRAND_STROKE_PATH_SMALL` opens the cut to 7.2 units and `BRAND_POINT_SMALL` slides the point 10 units out of its cradle, opening the crescent from 7.26 to 11.55. Only the favicon and the raster icon routes used them. Nothing in the app did. **The one thing that did not exist, and how it was derived rather than drawn.** The bare (untiled) glyph had no small-size placement. `brand-mark.ts` says in terms not to redraw the construction by hand, and this does not: the doc fixes both ink boxes (display spans 0-55.33, chrome 0-65.33, both 0-100.38 tall) and every committed placement centres that box in the 512 viewBox — verified against all three, each landing on 256.000 within 0.003, the rounding of a two-decimal box figure. Two consequences follow arithmetically. The point keeps its `cy` and `r`, so the vertical extent is identical and the scale is unchanged at 5.1006 (100.3813 x 5.1006 = 512.0, which is the bare variant's whole purpose). The point moves exactly 10 units and is the box's right edge, so the box widens by 10 and its centre by 5: 114.8907 - 5 x 5.1006 = 89.3877. The same arithmetic reproduces the committed tiled pair (143.1125 - 5 x 4.0804 = 122.7103, as shipped), which is the check that this is the rule actually in use rather than one that merely fits. **Threshold.** 32px, from the doc's own "at 32 px and below two things close up". Sub-32px production sites now draw the chrome cut: the collapsed sidebar rail (28px), the phone drawer header (28/32px), the account-setup workspace mark (32px), and the ward sidebar glyph (32px). Everything at 36px and above keeps the display cut. Design-scratch mockups are untouched. The three pieces are selected together through one `brandMarkOptics()` call, so a caller cannot half-apply the variant — the doc is explicit that mixing one variant's point with the other's placement puts the glyph off-centre. Verification - `tests/brand-mark-optics.test.ts` — 14 passed. Every rule mutation-tested with the failure predicted before running: dropping `optical="chrome"` from a 28px site, adding it to a 40px one, shifting the new transform 5px off centre, and pairing the chrome placement with the display point each failed exactly the intended assertion; all four restored byte-identical. - Writing that test surfaced a defect in the test itself, fixed before it could mislead: `ward-management-navigation.tsx` imports two CSS modules that BOTH define `.brandGlyph`, at 2.5rem and 2rem, so an identifier-blind resolver merged them and reported real sites as spanning the threshold. It now resolves the specific import. It also caught `sidebar-live-mockup.tsx` — design scratch named with the singular `-mockup`, which the usual `mockups` filter misses. - `npm run brand:check` — `src/app/icon.svg matches the brand-mark source` (this adds exports; it changes no existing value, so the generated assets are untouched). - Design-system contract passed, every ratchet at or under baseline; adoption 55 components / 84 roots; design-sync contract 55 components / 7 guidelines. - Full unit suite: `11744 passed | 1 skipped` across 931 files. Three pre-existing failures in `clinical-hazard-controls`, `privacy-readiness-contract` and `rag-plan-package-parity` — none touches brand geometry, and CI's Unit coverage passed these on the previous PR, so they are container-local. - Lint clean at `--max-warnings 0`; typecheck exit 0, unscoped; whole-tree format committed with the work. RAG impact: no retrieval behaviour change - this diff touches no file under src/lib/rag/** and none of the protected ranking surfaces (clinical-search, retrieval-selection, released-search-order, ranking-config, answer-ranking, answer-verification), adds no comparator key, and leaves the golden fixture and eval harness untouched. Verified by listing the diff's paths against that set. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YRGeyyiZNrXnFJjVVnykgp
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_af682cf9-ba34-46c9-adaa-555d889418af) |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Summary
--brand-mark-emphasisink. The ink stays; the cause is now addressed rather than offset.docs/brand/psychsift-logo.md§"Small sizes" calls for it, andbrand-mark.tsalready exportsBRAND_STROKE_PATH_SMALL(cut opened to 7.2 units) andBRAND_POINT_SMALL(point slid 10 units out of its cradle, crescent opened from 7.26 to 11.55). Only the favicon and the raster icon routes consumed them.brandMarkOptics()call, so a caller cannot half-apply the variant — the brand doc is explicit that mixing one variant's point with the other's placement puts the glyph off-centre in its box.The one thing that did not exist, and how it was derived rather than drawn
The bare (untiled) glyph had no small-size placement.
brand-mark.tssays in terms not to redraw the construction by hand, and this does not.The doc fixes both ink boxes — display spans 0–55.33, chrome 0–65.33, both 0–100.38 tall — and every committed placement centres that box in the 512 viewBox. That rule was checked against all three existing transforms before anything was written: each lands its centre on 256.000 within 0.003, the rounding of a two-decimal box figure.
Two consequences then follow arithmetically rather than by eye:
cyandr, so the vertical extent is identical and the scale is unchanged at 5.1006 —100.3813 × 5.1006 = 512.0, which is the bare variant's whole purpose.114.8907 − 5 × 5.1006 = 89.3877.The same arithmetic reproduces the committed tiled pair (
143.1125 − 5 × 4.0804 = 122.7103, as shipped). That is the check that this is the rule actually in use, not merely one that fits the numbers.Threshold is 32px, from the doc's own "at 32 px and below two things close up". Below ~20px the crescent is under two pixels whatever is done; that is the size, not the placement, and no variant rescues it.
Verification
tests/brand-mark-optics.test.ts— 14 passed. Every new rule mutation-tested with the failure predicted before running, then compared against observed: droppingoptical="chrome"from a 28px site, adding it to a 40px one, shifting the new transform 5px off centre, and pairing the chrome placement with the display point each failed exactly the intended assertion (1 failed,2 failed,3 failed,2 failedrespectively). All four restored byte-identical.ward-management-navigation.tsximports two CSS modules that both define.brandGlyph, at 2.5rem and 2rem; an identifier-blind resolver merged them and reported real call sites as spanning the threshold — a helper bug that reads exactly like a source bug. It now resolves the specific import identifier. The same run caughtsidebar-live-mockup.tsx, design scratch named with the singular-mockup, which the usualmockupsfilter misses.npm run brand:check—✓ brand: src/app/icon.svg matches the brand-mark source.This change adds exports and alters no existing value, so the generated assets are untouched.npm run check:design-system-contract— passed, every ratchet at or under baseline (sub-floor interactive min-heights 2, matching). Adoption 55 components / 84 roots; design-sync contract 55 components / 7 guidelines.npm run buildon a cleared.next— succeeded,Client bundle secret surface check passed.npm run test—11744 passed | 1 skippedacross 931 files. Three pre-existing failures inclinical-hazard-controls,privacy-readiness-contractandrag-plan-package-parity, reproduced identically on a cleanorigin/maincheckout in this same container (3 failed | 22 passed). None touches brand geometry, and CI'sUnit coveragepassed all three on feat(design-system): give the brand a written identity and a per-ground mark #2462, so they are container-local rather than repository defects.npm run lintclean at--max-warnings 0;npm run typecheckexit 0, unscoped;npm run formatwhole-tree, committed with the work.UI verification not run:
npm run verify:uineeds a dev server and a Chromium pass I did not confirm ready in this container; the Chromium journeys in CI are the gate of record. Worth stating plainly — this change is visual, and the evidence above is arithmetic and structural, not a rendered comparison. The geometry is the brand's own committed artwork and the placement is verified against the rule the existing transforms already follow, but nobody has yet looked at the new cut on a phone. That is the one check this PR cannot supply.Risk and rollout
dattribute, one circle'scx, and atransformchange, on marks rendered at 28–32px. The outer silhouette is identical between the two cuts by construction — only the facing edges and the point move — so this cannot alter the mark's footprint or the space it occupies.opticalprop defaults todisplay, so reverting the call sites alone restores the previous appearance without touching the geometry exports.src/lib/rag/**and none of the protected ranking surfaces (clinical-search, retrieval-selection, released-search-order, ranking-config, answer-ranking, answer-verification), adds no comparator key, and leaves the golden fixture and eval harness untouched. Verified by listing the diff's seven paths against that set.Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy)Notes against those items, in full rather than as ticks alone.
This change introduces no retrieval path, no source-backed claim, no clinical content, no copy and no new data. It changes which of two committed vector constructions is drawn for the brand mark at small sizes. No Supabase target, migration, credential or document-access path is touched, and nothing added here runs server-side.
There is no clinical surface in this diff. The nearest thing is the account-setup workspace mark and the ward sidebar glyph, and in both cases the change is the logo's own geometry — no clinical value, status, badge, threshold or absence wording is involved, and nothing about what any page discloses or how it degrades has moved.
Failure behaviour is unchanged. Nothing here sits on a degradation path:
brandMarkOptics()is a pure selector over build-time constants with adisplaydefault, so an unrecognised or absent variant draws the primary construction rather than nothing. The mark renders identically whether or not any runtime data resolves.Notes
Still open, and still the owner's call: the phone chrome band on the privacy route paints
--surface-glassat 95%, which reads whiter than the tinted page beneath it and leaves a seam the mark appears to float on. It was raised in #2462 and remains unaddressed here for the same reason — moving a phone chrome ground isdocs/search-chrome-behaviour.mdterritory and wantsverify:phone-chromeevidence of its own. It is a separate change, not a line to slip into this one.Also unchanged and not fixable from the repository: Cursor Bugbot has now failed to run on two consecutive PRs against a Cursor usage/spend limit, so it has reviewed neither. That is an account setting, not a code problem.
Generated by Claude Code
Note
Low Risk
Visual-only SVG geometry in navigation chrome; no auth, data, or API changes, with
opticaldefaulting to prior behavior if call sites are reverted.Overview
Adds an
opticalprop onBrandMark(displayvschrome) wired throughbrandMarkOptics(), so stroke path, point, and centring transform are always chosen as one variant.brand-mark.tsgains the derived bare small placementBRAND_GLYPH_TRANSFORM_BARE_SMALLalongside the existing small stroke/point geometry that favicons already used.Sub-32px chrome (collapsed clinical rail, mobile drawer header, account-setup mark, Ward Flow phone bar/drawer/sidebar row) now passes
optical="chrome"so the widened stroke gap and shifted point render instead of the display construction that was fusing at small sizes. Larger marks (e.g. expanded sidebarh-10) keep the defaultdisplaycut.tests/brand-mark-optics.test.tslocks centring arithmetic and scans productionBrandMarkcall sites so render height and optical choice stay aligned with the 32px threshold.Reviewed by Cursor Bugbot for commit 33a7bd4. Configure here.